﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Data.SqlClient;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Mail;

namespace CheckingServiceDongBo
{
    public enum ChangeType
    {
        None = 0, Insert = 1, Update = 2, Delete = 3
    }

    public partial class CheckingServiceDongBo : ServiceBase
    {
        public CheckingServiceDongBo()
        {
            InitializeComponent();
        }

        //Một số server parameter
        //Server Name   SMTP Address	        Port	SSL
        //Yahoo!	    smtp.mail.yahoo.com	    587	    Yes
        //GMail	        smtp.gmail.com	        587	    Yes
        //Hotmail	    smtp.live.com	        587	    Yes

        string smtpAddress = "smtp.gmail.com";
        int portNumber = 587;
        bool enableSSL = true;

        string emailFrom = "hattieuit88@gmail.com";
        string password = "hoabattu";
        string emailTo = "vuongquangphuong@gmail.com";
        string subject = "";
        string body = "";

        private void ReadFileSettingsToLocalSettings()
        {
            //int counter = 1;
            //string[] line = new string[20]; //Đọc được 20 dòng

            //// Read the file and display it line by line.
            //System.IO.StreamReader file =
            //   new System.IO.StreamReader("c:\\SynSettings.txt");
            //while ((line[counter] = file.ReadLine()) != null)
            //{
            //    counter++;
            //}
            //LocalSettings.HeThong.DB_Server = line[1];
            //LocalSettings.HeThong.DB_UID = line[2];
            //LocalSettings.HeThong.DB_PASS = line[3];
            //LocalSettings.HeThong.DB_Name = line[4];

            //LocalSettings.HeThong.DB_Server2 = line[5];
            //LocalSettings.HeThong.DB_UID2 = line[6];
            //LocalSettings.HeThong.DB_PASS2 = line[7];
            //LocalSettings.HeThong.DB_Name2 = line[8];

            //LocalSettings.HeThong.StoreName1 = line[9];
            //LocalSettings.HeThong.StoreName2 = line[10];

            //LocalSettings.HeThong.ChuKyTuDongDongBo = Convert.ToInt32(line[11]);
            //LocalSettings.HeThong.ChieuDongBo = (ChieuDongBo)Convert.ToInt32(line[12]);
            //LocalSettings.HeThong.KieuDongBo = (KieuDongBo)Convert.ToInt32(line[13]);

            //file.Close();

            //Server 117
            _LstConectString.Add(string.Format("SERVER = 117.6.85.20; DATABASE = HuyHoangCenter; UID= sa; PWD=sqlP2ssw0rd"));
            _LstConectString.Add(string.Format("SERVER = 117.6.85.20; DATABASE = BachKhoaCenter; UID= sa; PWD=sqlP2ssw0rd"));
            _LstConectString.Add(string.Format("SERVER = 117.6.85.20; DATABASE = ThanhVinh1Center; UID= sa; PWD=sqlP2ssw0rd"));
            _LstConectString.Add(string.Format("SERVER = 117.6.85.20; DATABASE = ThanhVinh2Center; UID= sa; PWD=sqlP2ssw0rd"));
            _LstConectString.Add(string.Format("SERVER = 117.6.85.20; DATABASE = TTSHNCenter; UID= sa; PWD=sqlP2ssw0rd"));
            //Server SG 177
            _LstConectString.Add(string.Format("SERVER = 113.161.79.177; DATABASE = KCBThanhHaCenter; UID= sa; PWD=srmdep"));
            _LstConectString.Add(string.Format("SERVER = 113.161.79.177; DATABASE = Minh277NVCCenter; UID= sa; PWD=srmdep"));
            _LstConectString.Add(string.Format("SERVER = 113.161.79.177; DATABASE = MinhCenter; UID= sa; PWD=srmdep"));
            _LstConectString.Add(string.Format("SERVER = 113.161.79.177; DATABASE = NTThanhBinhCenter; UID= sa; PWD=srmdep"));
            _LstConectString.Add(string.Format("SERVER = 113.161.79.177; DATABASE = TOTTOTCenter; UID= sa; PWD=srmdep"));
            //Server SG 165
            _LstConectString.Add(string.Format("SERVER = 113.161.58.165; DATABASE = VIP12Center; UID= sa; PWD=srmdep"));
            //Server NQD
            _LstConectString.Add(string.Format("SERVER = 118.70.80.112; DATABASE = CPIN_18PH_2017Center; UID= sa; PWD=srmdep"));
            _LstConectString.Add(string.Format(@"SERVER = 118.70.80.112\sqlexpress,5000; DATABASE = DuocMinhHangCenter; UID= sa; PWD=srmdep"));
        }

        private System.Threading.Timer _timer;
        protected override void OnStart(string[] args)
        {
            System.Diagnostics.Debugger.Launch();
            try
            {
                if (LocalSettings.HeThong == null)
                {
                    LocalSettings.HeThong = new LocalSettings();
                }

                ReadFileSettingsToLocalSettings();
                Use_Notify();

                CheckSynData();

                TimerCallback callback = new TimerCallback(OnTimedEvent);
                _timer = new System.Threading.Timer(callback, null, 60000 * 3600, 60000 * 3600); 
            }
            catch (Exception ex)
            {
            }
        }

        private void OnTimedEvent(Object stateInfo)
        {
            Console.WriteLine("da tich:" + DateTime.Now);

            TimeSpan duration = DateTime.Now - LocalSettings.HeThong.LastUpdate;

            try
            {
                if (duration.TotalMinutes >= LocalSettings.HeThong.ChuKyTuDongDongBo)
                {
                    LocalSettings.HeThong.LastUpdate = DateTime.Now;

                    _timer.Change(60000 * 3600, 60000 * 3600);//Như là Stop đồng hồ lại 1h sau mới gọi callback (tick) tiếp
                    CheckSynData();
                    //_timer.Change(60000, 60000 * LocalSettings.HeThong.ChuKyTuDongDongBo);//Như là Start đồng hồ lại 1h sau mới gọi callback (tick) tiếp
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Không chạy tự đồng bộ theo chu kì được.\n Lỗi: " + ex.Message);
            }
        }

        protected override void OnStop()
        {
            _timer.Dispose();
            this.notifyIcon.Dispose();
        }

        SqlDataAdapter _DataAdapter = new SqlDataAdapter();
        string _ErrorMessage = "";

        private bool CheckConnectServer(string connectionString)
        {
            //FrmProgressBar.StartShowProgress("Kiểm tra kết nối");
            using (SqlConnection con = new SqlConnection())
            {
                con.ConnectionString = connectionString;
                try
                {
                    con.Open();
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                }
                finally
                {
                    //FrmProgressBar.FinishShowProgress();
                    if (con.State == ConnectionState.Open) con.Close();
                }
            }
        }       //Kiểm tra kết nối đến server
        private void Use_Notify()
        {
            LocalSettings.HeThong.TuDongDongBo = true;

            notifyIcon.ContextMenuStrip = contextMenuStrip;
            notifyIcon.BalloonTipText = "Chương trình kiểm tra dịch vụ đồng bộ";
            notifyIcon.BalloonTipTitle = "Chương trình kiểm tra dịch vụ đồng bộ";
            notifyIcon.ShowBalloonTip(1);
        }        //Hiển thị Notify nếu để ở chế độ minimaze

        private void ShowMessageAutoClose(string message, string caption, uint timerStopShowMessage, bool fromSynProcess, bool sendEmail)
        {
            try
            {
                notifyIcon.BalloonTipText = message;
                notifyIcon.BalloonTipTitle = caption;
                notifyIcon.ShowBalloonTip(1);

                if (sendEmail) SendEmail(message, caption);
            }
            catch (Exception ex)
            {
                throw new Exception("Lỗi menthod hiện thông báo: " + ex.Message);
            }
        }
        private void ShowMessageAutoClose(string message, string caption, uint timerStopShowMessage, bool fromSynProcess, bool sendEmail, string sql1, string sql2)
        {
            try
            {
                notifyIcon.BalloonTipText = message;
                notifyIcon.BalloonTipTitle = caption;
                notifyIcon.ShowBalloonTip(1);

                if (sendEmail) SendEmail(message, caption, sql1, sql2);
            }
            catch (Exception ex)
            {
                throw new Exception("Lỗi menthod hiện thông báo: " + ex.Message);
            }
        }
        private void SendEmail(string error, string caption)
        {
            try
            {
                TimeSpan span = DateTime.Now - LocalSettings.HeThong.LastSendEmail;

                //if (Math.Abs(span.Minutes) >= 30)  //30 phút gửi 1 email, không gmail cho vào spam 
                //{
                    //subject = TenCuaHang1 + " đến " + TenCuaHang2 + " - " + CommonLib.DateTimeVNToString(DateTime.Now);
                    //body = string.Format("Caption: {0}.     Error: {1}", caption, error);

                    using (MailMessage mail = new MailMessage())
                    {
                        mail.From = new MailAddress(emailFrom);
                        mail.To.Add(emailTo);
                        mail.Subject = subject;
                        mail.Body = body;
                        mail.IsBodyHtml = true;
                        // Can set to false, if you are sending pure text.

                        //mail.Attachments.Add(new Attachment("C:\\SomeFile.txt"));
                        //mail.Attachments.Add(new Attachment("C:\\SomeZip.zip"));

                        SmtpClient smtp = new SmtpClient(smtpAddress, portNumber);
                        smtp.Credentials = new NetworkCredential(emailFrom, password);
                        smtp.EnableSsl = enableSSL;
                        smtp.Send(mail);
                        LocalSettings.HeThong.LastSendEmail = DateTime.Now;
                    }
                //}
            }
            catch (Exception ex)
            {
            }
        }
        private void SendEmail()
        {
            try
            {
                TimeSpan span = DateTime.Now - LocalSettings.HeThong.LastSendEmail;

                //if (Math.Abs(span.Minutes) >= 30)  //30 phút gửi 1 email, không gmail cho vào spam 
                //{
                //subject = TenCuaHang1 + " đến " + TenCuaHang2 + " - " + CommonLib.DateTimeVNToString(DateTime.Now);
                //body = string.Format("Caption: {0}.     Error: {1}", caption, error);

                using (MailMessage mail = new MailMessage())
                {
                    mail.From = new MailAddress(emailFrom);
                    mail.To.Add(emailTo);
                    mail.Subject = subject;
                    mail.Body = body;
                    mail.IsBodyHtml = true;
                    // Can set to false, if you are sending pure text.

                    //mail.Attachments.Add(new Attachment("C:\\SomeFile.txt"));
                    //mail.Attachments.Add(new Attachment("C:\\SomeZip.zip"));

                    SmtpClient smtp = new SmtpClient(smtpAddress, portNumber);
                    smtp.Credentials = new NetworkCredential(emailFrom, password);
                    smtp.EnableSsl = enableSSL;
                    smtp.Send(mail);
                    LocalSettings.HeThong.LastSendEmail = DateTime.Now;
                }
                //}
            }
            catch (Exception ex)
            {
            }
        }
        private void SendEmail(string error, string caption, string sql1, string sql2)
        {
            try
            {
                TimeSpan span = DateTime.Now - LocalSettings.HeThong.LastSendEmail;

                if (Math.Abs(span.Minutes) >= 30)  //30 phút gửi 1 email, không gmail cho vào spam 
                {
                    //subject = TenCuaHang1 + " đến " + TenCuaHang2 + " - " + CommonLib.DateTimeVNToString(DateTime.Now); ;
                    //body = string.Format("Caption: {0}.     Error: {1}.     Sql1 (by cmd1): {2}.        Sql2 (by cmd2): {3}",
                    //    caption, error, sql1, sql2);

                    using (MailMessage mail = new MailMessage())
                    {
                        mail.From = new MailAddress(emailFrom);
                        mail.To.Add(emailTo);
                        mail.Subject = subject;
                        mail.Body = body;
                        mail.IsBodyHtml = true;
                        // Can set to false, if you are sending pure text.

                        //mail.Attachments.Add(new Attachment("C:\\SomeFile.txt"));
                        //mail.Attachments.Add(new Attachment("C:\\SomeZip.zip"));

                        SmtpClient smtp = new SmtpClient(smtpAddress, portNumber);
                        smtp.Credentials = new NetworkCredential(emailFrom, password);
                        smtp.EnableSsl = enableSSL;
                        smtp.Send(mail);
                        LocalSettings.HeThong.LastSendEmail = DateTime.Now;
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {

        }

        List<string> _LstConectString = new List<string>();

        private void CheckSynData()
        {
            if (DateTime.Now.Hour == 10 || DateTime.Now.Hour == 15)
            {
            }
            else
            {
                return;
            }

            string noidungEmail = "";
            subject = string.Format("[DongBoDuLieu] Bị lỗi - check ngày {0}", DateTime.Now.ToString());
            SqlConnection con = new SqlConnection();
           
            foreach (string connectionString in _LstConectString)
	        {
		        con.ConnectionString = connectionString;

                try 
	            {	        
                    //B1: tạo các kết nối đến các CSDL
                    con.Open();

                    //B2: Truy vấn CSDL
                    SqlCommand cmd = con.CreateCommand();
                    SqlDataAdapter da = new SqlDataAdapter();
                    DataTable dtCheck = new DataTable();

                    cmd.CommandText = "SELECT TOP 20 * FROM ChungTu WHERE Ngay <= GETDATE() ORDER BY Ngay DESC";
                    cmd.CommandType = CommandType.Text;

                    da.SelectCommand = cmd;
                    da.Fill(dtCheck);

                    //B3: Check ngày của dữ liệu
                    //Check lúc 11h sáng và 3h chiều ==> phải có toàn bộ 20 bản ghi là ngày hôm đó, vì giờ khá sâu và k tính những dòng insert lỗi quá ngày
                    bool ok = true;
                    foreach (DataRow row in dtCheck.Rows)
	                {
		                if(row["Ngay"] is DateTime)
                        {
                            TimeSpan span = (DateTime)row["Ngay"] - DateTime.Now;
                            if(span.Days != 0)
                                ok = false;
                        }
	                }
                    if(ok == false)
                    {
                        if(con.Database != null)
                            noidungEmail += string.Format("Database: {0} ---- \n", con.Database);
                        else
                            noidungEmail += string.Format("Database: {0} ---- \n", connectionString);
                    }
	            }
	            catch (Exception)
	            {
                        if(con.Database != null)
                            noidungEmail += string.Format("Không kết nối được đến Database: {0} ---- \n", con.Database);
                        else
                            noidungEmail += string.Format("Không kết nối được đến Database: {0} ---- \n", connectionString);
	            }
                finally
                {
                    if (con.State == ConnectionState.Open) con.Close();
                }
	        }

            if (noidungEmail != "")
            {
                body = noidungEmail;
                SendEmail();
            }
        }
    }
}
